Amazon DynamoDB の UpdateItem の Add 構文による数値計算で、小数点以下の誤差が出ないのか確認してみた
こんにちは、CX事業本部 Delivery部の若槻です。
Amazon DynamoDB でテーブル上のアイテムの数値属性を UpdateItem を使用して更新する際に、Add 構文を使用して加減計算を行うことができます。
次のような記述で、更新前の値を取得することなく値の足し算または引き算が可能なので、ロックを考慮する必要がありません。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "ADD QuantityOnHand :q" \ --expression-attribute-values '{":q": {"N": "5"}}' \ --return-values ALL_NEW
さてこのとても便利な Add 構文ですが、計算される側またはする側の値が少数の時に、浮動小数点による計算誤差は出ないのでしょうか?気になったので検証してみました。
試してみた
テーブル作成
AWS CDK で検証用のテーブルを作成します。
import { aws_dynamodb, Stack, CfnOutput } from 'aws-cdk-lib'; import { Construct } from 'constructs'; export class CdkSampleStack extends Stack { constructor(scope: Construct, id: string) { super(scope, id); const table = new aws_dynamodb.Table(this, 'Table', { partitionKey: { name: 'id', type: aws_dynamodb.AttributeType.STRING }, billingMode: aws_dynamodb.BillingMode.PAY_PER_REQUEST, }); new CfnOutput(this, 'TableName', { value: table.tableName, }); } }
検証用スクリプト
0.01 から 1 までの値を設定した 100 個の属性を持つアイテムを PutItem で作成し、それら属性に対して同じ値を加算(減算)する UpdateItem を実行するスクリプトです。AWS SDK for JavaScript v3 を使用しています。
import { marshall, unmarshall } from '@aws-sdk/util-dynamodb'; import { PutItemCommand, PutItemCommandInput, UpdateItemCommand, UpdateItemCommandInput, DynamoDBClient, ReturnValue, } from '@aws-sdk/client-dynamodb'; const ADDITION = Number(process.argv[2]) || 0.01; const TABLE_NAME = process.env.TABLE_NAME || ''; const client = new DynamoDBClient({ region: 'ap-northeast-1', }); const numValues = Array.from(Array(100), (_, i) => (i + 1) / 100); const numValueAttrs = numValues.map( (numValue) => `numValue${numValue.toString().replace('.', '')}` ); export const main = async (addition: number): Promise<void> => { // PutItem: numValue001: 0.01 から numValue1: 1.00 までの値を設定 const putObject = numValues.reduce((acc, numValue) => { return { ...acc, [`numValue${numValue.toString().replace('.', '')}`]: numValue, }; }, {}); const putParams: PutItemCommandInput = { TableName: TABLE_NAME, Item: marshall({ id: 'test', ...putObject, }), }; await client.send(new PutItemCommand(putParams)); // UpdateItem: numValue001 から numValue1 までの属性値を、指定値ずつ加算 const expressionAttributeNames = numValueAttrs.reduce( (acc, numValueAttr) => ({ ...acc, [`#${numValueAttr}`]: numValueAttr, }), {} ); const updateExpression = `SET ${numValueAttrs .map((numValueAttr) => `#${numValueAttr} = #${numValueAttr} + :numValue`) .join(', ')}`; const updateParams: UpdateItemCommandInput = { TableName: TABLE_NAME, Key: marshall({ id: 'test', }), UpdateExpression: updateExpression, ExpressionAttributeNames: expressionAttributeNames, ExpressionAttributeValues: marshall({ ':numValue': addition, }), ReturnValues: ReturnValue.ALL_NEW, }; const updateResult = await client.send(new UpdateItemCommand(updateParams)); const updatedItem = unmarshall(updateResult.Attributes!); const updateObject = Object.keys(updatedItem) .sort() .reduce((acc, key) => { return { ...acc, [key]: updatedItem[key], }; }, {}); // putObject と updateObject の比較をテーブル形式で出力 const keys = Object.keys(putObject); const values = keys.map((key) => ({ key, putValue: (putObject as any)[key], updateValue: (updateObject as any)[key], })); const table = values.reduce((acc, value) => { return `${acc}${value.key}\t${value.putValue}\t${value.updateValue}\n`; }, ''); console.log(table); }; main(ADDITION);
検証
その1
各属性に 0.01
を加算した場合。
$ npx ts-node script.ts numValue001 0.01 0.02 numValue002 0.02 0.03 numValue003 0.03 0.04 numValue004 0.04 0.05 numValue005 0.05 0.06 numValue006 0.06 0.07 numValue007 0.07 0.08 numValue008 0.08 0.09 numValue009 0.09 0.1 numValue01 0.1 0.11 numValue011 0.11 0.12 numValue012 0.12 0.13 numValue013 0.13 0.14 numValue014 0.14 0.15 numValue015 0.15 0.16 numValue016 0.16 0.17 numValue017 0.17 0.18 numValue018 0.18 0.19 numValue019 0.19 0.2 numValue02 0.2 0.21 numValue021 0.21 0.22 numValue022 0.22 0.23 numValue023 0.23 0.24 numValue024 0.24 0.25 numValue025 0.25 0.26 numValue026 0.26 0.27 numValue027 0.27 0.28 numValue028 0.28 0.29 numValue029 0.29 0.3 numValue03 0.3 0.31 numValue031 0.31 0.32 numValue032 0.32 0.33 numValue033 0.33 0.34 numValue034 0.34 0.35 numValue035 0.35 0.36 numValue036 0.36 0.37 numValue037 0.37 0.38 numValue038 0.38 0.39 numValue039 0.39 0.4 numValue04 0.4 0.41 numValue041 0.41 0.42 numValue042 0.42 0.43 numValue043 0.43 0.44 numValue044 0.44 0.45 numValue045 0.45 0.46 numValue046 0.46 0.47 numValue047 0.47 0.48 numValue048 0.48 0.49 numValue049 0.49 0.5 numValue05 0.5 0.51 numValue051 0.51 0.52 numValue052 0.52 0.53 numValue053 0.53 0.54 numValue054 0.54 0.55 numValue055 0.55 0.56 numValue056 0.56 0.57 numValue057 0.57 0.58 numValue058 0.58 0.59 numValue059 0.59 0.6 numValue06 0.6 0.61 numValue061 0.61 0.62 numValue062 0.62 0.63 numValue063 0.63 0.64 numValue064 0.64 0.65 numValue065 0.65 0.66 numValue066 0.66 0.67 numValue067 0.67 0.68 numValue068 0.68 0.69 numValue069 0.69 0.7 numValue07 0.7 0.71 numValue071 0.71 0.72 numValue072 0.72 0.73 numValue073 0.73 0.74 numValue074 0.74 0.75 numValue075 0.75 0.76 numValue076 0.76 0.77 numValue077 0.77 0.78 numValue078 0.78 0.79 numValue079 0.79 0.8 numValue08 0.8 0.81 numValue081 0.81 0.82 numValue082 0.82 0.83 numValue083 0.83 0.84 numValue084 0.84 0.85 numValue085 0.85 0.86 numValue086 0.86 0.87 numValue087 0.87 0.88 numValue088 0.88 0.89 numValue089 0.89 0.9 numValue09 0.9 0.91 numValue091 0.91 0.92 numValue092 0.92 0.93 numValue093 0.93 0.94 numValue094 0.94 0.95 numValue095 0.95 0.96 numValue096 0.96 0.97 numValue097 0.97 0.98 numValue098 0.98 0.99 numValue099 0.99 1 numValue1 1 1.01
大丈夫そうです。
その2
各属性に 0.1
を加算した場合。
$ npx ts-node script.ts 0.1 numValue001 0.01 0.11 numValue002 0.02 0.12 numValue003 0.03 0.13 numValue004 0.04 0.14 numValue005 0.05 0.15 numValue006 0.06 0.16 numValue007 0.07 0.17 numValue008 0.08 0.18 numValue009 0.09 0.19 numValue01 0.1 0.2 numValue011 0.11 0.21 numValue012 0.12 0.22 numValue013 0.13 0.23 numValue014 0.14 0.24 numValue015 0.15 0.25 numValue016 0.16 0.26 numValue017 0.17 0.27 numValue018 0.18 0.28 numValue019 0.19 0.29 numValue02 0.2 0.3 numValue021 0.21 0.31 numValue022 0.22 0.32 numValue023 0.23 0.33 numValue024 0.24 0.34 numValue025 0.25 0.35 numValue026 0.26 0.36 numValue027 0.27 0.37 numValue028 0.28 0.38 numValue029 0.29 0.39 numValue03 0.3 0.4 numValue031 0.31 0.41 numValue032 0.32 0.42 numValue033 0.33 0.43 numValue034 0.34 0.44 numValue035 0.35 0.45 numValue036 0.36 0.46 numValue037 0.37 0.47 numValue038 0.38 0.48 numValue039 0.39 0.49 numValue04 0.4 0.5 numValue041 0.41 0.51 numValue042 0.42 0.52 numValue043 0.43 0.53 numValue044 0.44 0.54 numValue045 0.45 0.55 numValue046 0.46 0.56 numValue047 0.47 0.57 numValue048 0.48 0.58 numValue049 0.49 0.59 numValue05 0.5 0.6 numValue051 0.51 0.61 numValue052 0.52 0.62 numValue053 0.53 0.63 numValue054 0.54 0.64 numValue055 0.55 0.65 numValue056 0.56 0.66 numValue057 0.57 0.67 numValue058 0.58 0.68 numValue059 0.59 0.69 numValue06 0.6 0.7 numValue061 0.61 0.71 numValue062 0.62 0.72 numValue063 0.63 0.73 numValue064 0.64 0.74 numValue065 0.65 0.75 numValue066 0.66 0.76 numValue067 0.67 0.77 numValue068 0.68 0.78 numValue069 0.69 0.79 numValue07 0.7 0.8 numValue071 0.71 0.81 numValue072 0.72 0.82 numValue073 0.73 0.83 numValue074 0.74 0.84 numValue075 0.75 0.85 numValue076 0.76 0.86 numValue077 0.77 0.87 numValue078 0.78 0.88 numValue079 0.79 0.89 numValue08 0.8 0.9 numValue081 0.81 0.91 numValue082 0.82 0.92 numValue083 0.83 0.93 numValue084 0.84 0.94 numValue085 0.85 0.95 numValue086 0.86 0.96 numValue087 0.87 0.97 numValue088 0.88 0.98 numValue089 0.89 0.99 numValue09 0.9 1 numValue091 0.91 1.01 numValue092 0.92 1.02 numValue093 0.93 1.03 numValue094 0.94 1.04 numValue095 0.95 1.05 numValue096 0.96 1.06 numValue097 0.97 1.07 numValue098 0.98 1.08 numValue099 0.99 1.09 numValue1 1 1.1
大丈夫そうです。
その3
各属性に 0.001
を加算した場合。
$ npx ts-node script.ts 0.001 numValue001 0.01 0.011 numValue002 0.02 0.021 numValue003 0.03 0.031 numValue004 0.04 0.041 numValue005 0.05 0.051 numValue006 0.06 0.061 numValue007 0.07 0.071 numValue008 0.08 0.081 numValue009 0.09 0.091 numValue01 0.1 0.101 numValue011 0.11 0.111 numValue012 0.12 0.121 numValue013 0.13 0.131 numValue014 0.14 0.141 numValue015 0.15 0.151 numValue016 0.16 0.161 numValue017 0.17 0.171 numValue018 0.18 0.181 numValue019 0.19 0.191 numValue02 0.2 0.201 numValue021 0.21 0.211 numValue022 0.22 0.221 numValue023 0.23 0.231 numValue024 0.24 0.241 numValue025 0.25 0.251 numValue026 0.26 0.261 numValue027 0.27 0.271 numValue028 0.28 0.281 numValue029 0.29 0.291 numValue03 0.3 0.301 numValue031 0.31 0.311 numValue032 0.32 0.321 numValue033 0.33 0.331 numValue034 0.34 0.341 numValue035 0.35 0.351 numValue036 0.36 0.361 numValue037 0.37 0.371 numValue038 0.38 0.381 numValue039 0.39 0.391 numValue04 0.4 0.401 numValue041 0.41 0.411 numValue042 0.42 0.421 numValue043 0.43 0.431 numValue044 0.44 0.441 numValue045 0.45 0.451 numValue046 0.46 0.461 numValue047 0.47 0.471 numValue048 0.48 0.481 numValue049 0.49 0.491 numValue05 0.5 0.501 numValue051 0.51 0.511 numValue052 0.52 0.521 numValue053 0.53 0.531 numValue054 0.54 0.541 numValue055 0.55 0.551 numValue056 0.56 0.561 numValue057 0.57 0.571 numValue058 0.58 0.581 numValue059 0.59 0.591 numValue06 0.6 0.601 numValue061 0.61 0.611 numValue062 0.62 0.621 numValue063 0.63 0.631 numValue064 0.64 0.641 numValue065 0.65 0.651 numValue066 0.66 0.661 numValue067 0.67 0.671 numValue068 0.68 0.681 numValue069 0.69 0.691 numValue07 0.7 0.701 numValue071 0.71 0.711 numValue072 0.72 0.721 numValue073 0.73 0.731 numValue074 0.74 0.741 numValue075 0.75 0.751 numValue076 0.76 0.761 numValue077 0.77 0.771 numValue078 0.78 0.781 numValue079 0.79 0.791 numValue08 0.8 0.801 numValue081 0.81 0.811 numValue082 0.82 0.821 numValue083 0.83 0.831 numValue084 0.84 0.841 numValue085 0.85 0.851 numValue086 0.86 0.861 numValue087 0.87 0.871 numValue088 0.88 0.881 numValue089 0.89 0.891 numValue09 0.9 0.901 numValue091 0.91 0.911 numValue092 0.92 0.921 numValue093 0.93 0.931 numValue094 0.94 0.941 numValue095 0.95 0.951 numValue096 0.96 0.961 numValue097 0.97 0.971 numValue098 0.98 0.981 numValue099 0.99 0.991 numValue1 1 1.001
大丈夫そうです。
その4
各属性から 0.01
を減算した場合。
$ npx ts-node src/script.ts -0.01 numValue001 0.01 0 numValue002 0.02 0.01 numValue003 0.03 0.02 numValue004 0.04 0.03 numValue005 0.05 0.04 numValue006 0.06 0.05 numValue007 0.07 0.06 numValue008 0.08 0.07 numValue009 0.09 0.08 numValue01 0.1 0.09 numValue011 0.11 0.1 numValue012 0.12 0.11 numValue013 0.13 0.12 numValue014 0.14 0.13 numValue015 0.15 0.14 numValue016 0.16 0.15 numValue017 0.17 0.16 numValue018 0.18 0.17 numValue019 0.19 0.18 numValue02 0.2 0.19 numValue021 0.21 0.2 numValue022 0.22 0.21 numValue023 0.23 0.22 numValue024 0.24 0.23 numValue025 0.25 0.24 numValue026 0.26 0.25 numValue027 0.27 0.26 numValue028 0.28 0.27 numValue029 0.29 0.28 numValue03 0.3 0.29 numValue031 0.31 0.3 numValue032 0.32 0.31 numValue033 0.33 0.32 numValue034 0.34 0.33 numValue035 0.35 0.34 numValue036 0.36 0.35 numValue037 0.37 0.36 numValue038 0.38 0.37 numValue039 0.39 0.38 numValue04 0.4 0.39 numValue041 0.41 0.4 numValue042 0.42 0.41 numValue043 0.43 0.42 numValue044 0.44 0.43 numValue045 0.45 0.44 numValue046 0.46 0.45 numValue047 0.47 0.46 numValue048 0.48 0.47 numValue049 0.49 0.48 numValue05 0.5 0.49 numValue051 0.51 0.5 numValue052 0.52 0.51 numValue053 0.53 0.52 numValue054 0.54 0.53 numValue055 0.55 0.54 numValue056 0.56 0.55 numValue057 0.57 0.56 numValue058 0.58 0.57 numValue059 0.59 0.58 numValue06 0.6 0.59 numValue061 0.61 0.6 numValue062 0.62 0.61 numValue063 0.63 0.62 numValue064 0.64 0.63 numValue065 0.65 0.64 numValue066 0.66 0.65 numValue067 0.67 0.66 numValue068 0.68 0.67 numValue069 0.69 0.68 numValue07 0.7 0.69 numValue071 0.71 0.7 numValue072 0.72 0.71 numValue073 0.73 0.72 numValue074 0.74 0.73 numValue075 0.75 0.74 numValue076 0.76 0.75 numValue077 0.77 0.76 numValue078 0.78 0.77 numValue079 0.79 0.78 numValue08 0.8 0.79 numValue081 0.81 0.8 numValue082 0.82 0.81 numValue083 0.83 0.82 numValue084 0.84 0.83 numValue085 0.85 0.84 numValue086 0.86 0.85 numValue087 0.87 0.86 numValue088 0.88 0.87 numValue089 0.89 0.88 numValue09 0.9 0.89 numValue091 0.91 0.9 numValue092 0.92 0.91 numValue093 0.93 0.92 numValue094 0.94 0.93 numValue095 0.95 0.94 numValue096 0.96 0.95 numValue097 0.97 0.96 numValue098 0.98 0.97 numValue099 0.99 0.98 numValue1 1 0.99
大丈夫そうです。
その5
各属性に 0.000000000000001
を加算した場合。
$ npx ts-node src/script.ts 0.000000000000001 numValue001 0.01 0.010000000000001 numValue002 0.02 0.020000000000001 numValue003 0.03 0.030000000000001 numValue004 0.04 0.040000000000001 numValue005 0.05 0.050000000000001 numValue006 0.06 0.060000000000001 numValue007 0.07 0.070000000000001 numValue008 0.08 0.080000000000001 numValue009 0.09 0.090000000000001 numValue01 0.1 0.100000000000001 numValue011 0.11 0.110000000000001 numValue012 0.12 0.120000000000001 numValue013 0.13 0.130000000000001 numValue014 0.14 0.140000000000001 numValue015 0.15 0.150000000000001 numValue016 0.16 0.160000000000001 numValue017 0.17 0.170000000000001 numValue018 0.18 0.180000000000001 numValue019 0.19 0.190000000000001 numValue02 0.2 0.200000000000001 numValue021 0.21 0.210000000000001 numValue022 0.22 0.220000000000001 numValue023 0.23 0.230000000000001 numValue024 0.24 0.240000000000001 numValue025 0.25 0.250000000000001 numValue026 0.26 0.260000000000001 numValue027 0.27 0.270000000000001 numValue028 0.28 0.280000000000001 numValue029 0.29 0.290000000000001 numValue03 0.3 0.300000000000001 numValue031 0.31 0.310000000000001 numValue032 0.32 0.320000000000001 numValue033 0.33 0.330000000000001 numValue034 0.34 0.340000000000001 numValue035 0.35 0.350000000000001 numValue036 0.36 0.360000000000001 numValue037 0.37 0.370000000000001 numValue038 0.38 0.380000000000001 numValue039 0.39 0.390000000000001 numValue04 0.4 0.400000000000001 numValue041 0.41 0.410000000000001 numValue042 0.42 0.420000000000001 numValue043 0.43 0.430000000000001 numValue044 0.44 0.440000000000001 numValue045 0.45 0.450000000000001 numValue046 0.46 0.460000000000001 numValue047 0.47 0.470000000000001 numValue048 0.48 0.480000000000001 numValue049 0.49 0.490000000000001 numValue05 0.5 0.500000000000001 numValue051 0.51 0.510000000000001 numValue052 0.52 0.520000000000001 numValue053 0.53 0.530000000000001 numValue054 0.54 0.540000000000001 numValue055 0.55 0.550000000000001 numValue056 0.56 0.560000000000001 numValue057 0.57 0.570000000000001 numValue058 0.58 0.580000000000001 numValue059 0.59 0.590000000000001 numValue06 0.6 0.600000000000001 numValue061 0.61 0.610000000000001 numValue062 0.62 0.620000000000001 numValue063 0.63 0.630000000000001 numValue064 0.64 0.640000000000001 numValue065 0.65 0.650000000000001 numValue066 0.66 0.660000000000001 numValue067 0.67 0.670000000000001 numValue068 0.68 0.680000000000001 numValue069 0.69 0.690000000000001 numValue07 0.7 0.700000000000001 numValue071 0.71 0.710000000000001 numValue072 0.72 0.720000000000001 numValue073 0.73 0.730000000000001 numValue074 0.74 0.740000000000001 numValue075 0.75 0.750000000000001 numValue076 0.76 0.760000000000001 numValue077 0.77 0.770000000000001 numValue078 0.78 0.780000000000001 numValue079 0.79 0.790000000000001 numValue08 0.8 0.800000000000001 numValue081 0.81 0.810000000000001 numValue082 0.82 0.820000000000001 numValue083 0.83 0.830000000000001 numValue084 0.84 0.840000000000001 numValue085 0.85 0.850000000000001 numValue086 0.86 0.860000000000001 numValue087 0.87 0.870000000000001 numValue088 0.88 0.880000000000001 numValue089 0.89 0.890000000000001 numValue09 0.9 0.900000000000001 numValue091 0.91 0.910000000000001 numValue092 0.92 0.920000000000001 numValue093 0.93 0.930000000000001 numValue094 0.94 0.940000000000001 numValue095 0.95 0.950000000000001 numValue096 0.96 0.960000000000001 numValue097 0.97 0.970000000000001 numValue098 0.98 0.980000000000001 numValue099 0.99 0.990000000000001 numValue1 1 1.000000000000001
大丈夫そうです。
その6
各属性に 0.0000000000000001
を加算した場合。
$ npx ts-node src/script.ts 0.0000000000000001 numValue001 0.01 0.0100000000000001 numValue002 0.02 0.0200000000000001 numValue003 0.03 0.0300000000000001 numValue004 0.04 0.0400000000000001 numValue005 0.05 0.0500000000000001 numValue006 0.06 0.0600000000000001 numValue007 0.07 0.0700000000000001 numValue008 0.08 0.0800000000000001 numValue009 0.09 0.0900000000000001 numValue01 0.1 0.1000000000000001 numValue011 0.11 0.1100000000000001 numValue012 0.12 0.1200000000000001 numValue013 0.13 0.1300000000000001 numValue014 0.14 0.1400000000000001 numValue015 0.15 0.1500000000000001 numValue016 0.16 0.1600000000000001 numValue017 0.17 0.1700000000000001 numValue018 0.18 0.1800000000000001 numValue019 0.19 0.1900000000000001 numValue02 0.2 0.2000000000000001 numValue021 0.21 0.2100000000000001 numValue022 0.22 0.2200000000000001 numValue023 0.23 0.2300000000000001 numValue024 0.24 0.2400000000000001 numValue025 0.25 0.2500000000000001 numValue026 0.26 0.2600000000000001 numValue027 0.27 0.2700000000000001 numValue028 0.28 0.2800000000000001 numValue029 0.29 0.2900000000000001 numValue03 0.3 0.3000000000000001 numValue031 0.31 0.3100000000000001 numValue032 0.32 0.3200000000000001 numValue033 0.33 0.3300000000000001 numValue034 0.34 0.3400000000000001 numValue035 0.35 0.3500000000000001 numValue036 0.36 0.3600000000000001 numValue037 0.37 0.3700000000000001 numValue038 0.38 0.3800000000000001 numValue039 0.39 0.3900000000000001 numValue04 0.4 0.4000000000000001 numValue041 0.41 0.4100000000000001 numValue042 0.42 0.4200000000000001 numValue043 0.43 0.4300000000000001 numValue044 0.44 0.4400000000000001 numValue045 0.45 0.4500000000000001 numValue046 0.46 0.4600000000000001 numValue047 0.47 0.4700000000000001 numValue048 0.48 0.4800000000000001 numValue049 0.49 0.4900000000000001 numValue05 0.5 0.5000000000000001 numValue051 0.51 0.5100000000000001 numValue052 0.52 0.5200000000000001 numValue053 0.53 0.5300000000000001 numValue054 0.54 0.5400000000000001 numValue055 0.55 0.5500000000000002 numValue056 0.56 0.56 numValue057 0.57 0.5700000000000001 numValue058 0.58 0.5800000000000001 numValue059 0.59 0.5900000000000001 numValue06 0.6 0.6000000000000001 numValue061 0.61 0.6100000000000001 numValue062 0.62 0.6200000000000001 numValue063 0.63 0.6300000000000001 numValue064 0.64 0.6400000000000001 numValue065 0.65 0.6500000000000001 numValue066 0.66 0.6600000000000001 numValue067 0.67 0.6700000000000002 numValue068 0.68 0.68 numValue069 0.69 0.6900000000000001 numValue07 0.7 0.7000000000000001 numValue071 0.71 0.7100000000000001 numValue072 0.72 0.7200000000000001 numValue073 0.73 0.7300000000000001 numValue074 0.74 0.7400000000000001 numValue075 0.75 0.7500000000000001 numValue076 0.76 0.7600000000000001 numValue077 0.77 0.7700000000000001 numValue078 0.78 0.7800000000000001 numValue079 0.79 0.7900000000000001 numValue08 0.8 0.8000000000000002 numValue081 0.81 0.81 numValue082 0.82 0.8200000000000001 numValue083 0.83 0.8300000000000001 numValue084 0.84 0.8400000000000001 numValue085 0.85 0.8500000000000001 numValue086 0.86 0.8600000000000001 numValue087 0.87 0.8700000000000001 numValue088 0.88 0.8800000000000001 numValue089 0.89 0.8900000000000001 numValue09 0.9 0.9000000000000001 numValue091 0.91 0.9100000000000001 numValue092 0.92 0.9200000000000002 numValue093 0.93 0.93 numValue094 0.94 0.9400000000000001 numValue095 0.95 0.9500000000000001 numValue096 0.96 0.9600000000000001 numValue097 0.97 0.9700000000000001 numValue098 0.98 0.9800000000000001 numValue099 0.99 0.9900000000000001 numValue1 1 1
ここに来て誤差が発生しました。一部の属性で加算した少数が扱われなくなっています。
その7
各属性に 0.00000000000000001
を加算した場合。
$ npx ts-node src/script.ts 0.00000000000000001 numValue001 0.01 0.01000000000000001 numValue002 0.02 0.02000000000000001 numValue003 0.03 0.03000000000000001 numValue004 0.04 0.04000000000000001 numValue005 0.05 0.05000000000000001 numValue006 0.06 0.06000000000000001 numValue007 0.07 0.07 numValue008 0.08 0.08000000000000002 numValue009 0.09 0.09000000000000001 numValue01 0.1 0.1 numValue011 0.11 0.11000000000000001 numValue012 0.12 0.12000000000000001 numValue013 0.13 0.13 numValue014 0.14 0.14 numValue015 0.15 0.15000000000000002 numValue016 0.16 0.16 numValue017 0.17 0.17 numValue018 0.18 0.18000000000000002 numValue019 0.19 0.19 numValue02 0.2 0.2 numValue021 0.21 0.21000000000000002 numValue022 0.22 0.22 numValue023 0.23 0.23 numValue024 0.24 0.24000000000000002 numValue025 0.25 0.25 numValue026 0.26 0.26 numValue027 0.27 0.27 numValue028 0.28 0.28 numValue029 0.29 0.29000000000000004 numValue03 0.3 0.3 numValue031 0.31 0.31 numValue032 0.32 0.32 numValue033 0.33 0.33 numValue034 0.34 0.34 numValue035 0.35 0.35000000000000003 numValue036 0.36 0.36 numValue037 0.37 0.37 numValue038 0.38 0.38 numValue039 0.39 0.39 numValue04 0.4 0.4 numValue041 0.41 0.41000000000000003 numValue042 0.42 0.42 numValue043 0.43 0.43 numValue044 0.44 0.44 numValue045 0.45 0.45 numValue046 0.46 0.46 numValue047 0.47 0.47000000000000003 numValue048 0.48 0.48000000000000004 numValue049 0.49 0.49 numValue05 0.5 0.5 numValue051 0.51 0.51 numValue052 0.52 0.52 numValue053 0.53 0.53 numValue054 0.54 0.54 numValue055 0.55 0.55 numValue056 0.56 0.56 numValue057 0.57 0.5700000000000001 numValue058 0.58 0.58 numValue059 0.59 0.59 numValue06 0.6 0.6 numValue061 0.61 0.61 numValue062 0.62 0.62 numValue063 0.63 0.63 numValue064 0.64 0.64 numValue065 0.65 0.65 numValue066 0.66 0.66 numValue067 0.67 0.67 numValue068 0.68 0.68 numValue069 0.69 0.6900000000000001 numValue07 0.7 0.7 numValue071 0.71 0.71 numValue072 0.72 0.72 numValue073 0.73 0.73 numValue074 0.74 0.74 numValue075 0.75 0.75 numValue076 0.76 0.76 numValue077 0.77 0.77 numValue078 0.78 0.78 numValue079 0.79 0.79 numValue08 0.8 0.8 numValue081 0.81 0.81 numValue082 0.82 0.8200000000000001 numValue083 0.83 0.83 numValue084 0.84 0.84 numValue085 0.85 0.85 numValue086 0.86 0.86 numValue087 0.87 0.87 numValue088 0.88 0.88 numValue089 0.89 0.89 numValue09 0.9 0.9 numValue091 0.91 0.91 numValue092 0.92 0.92 numValue093 0.93 0.93 numValue094 0.94 0.9400000000000001 numValue095 0.95 0.95 numValue096 0.96 0.96 numValue097 0.97 0.97 numValue098 0.98 0.98 numValue099 0.99 0.99 numValue1 1 1
誤差が発生しました。一部の属性で加算した少数が扱われなくなっています。
その8
各属性に 0.000000000000000001
を加算した場合。
$ npx ts-node src/script.ts 0.000000000000000001 numValue001 0.01 0.01 numValue002 0.02 0.02 numValue003 0.03 0.030000000000000002 numValue004 0.04 0.04 numValue005 0.05 0.05 numValue006 0.06 0.06 numValue007 0.07 0.07 numValue008 0.08 0.08 numValue009 0.09 0.09 numValue01 0.1 0.1 numValue011 0.11 0.11 numValue012 0.12 0.12 numValue013 0.13 0.13 numValue014 0.14 0.14 numValue015 0.15 0.15 numValue016 0.16 0.16 numValue017 0.17 0.17 numValue018 0.18 0.18 numValue019 0.19 0.19 numValue02 0.2 0.2 numValue021 0.21 0.21 numValue022 0.22 0.22 numValue023 0.23 0.23 numValue024 0.24 0.24 numValue025 0.25 0.25 numValue026 0.26 0.26 numValue027 0.27 0.27 numValue028 0.28 0.28 numValue029 0.29 0.29 numValue03 0.3 0.3 numValue031 0.31 0.31 numValue032 0.32 0.32 numValue033 0.33 0.33 numValue034 0.34 0.34 numValue035 0.35 0.35 numValue036 0.36 0.36 numValue037 0.37 0.37 numValue038 0.38 0.38 numValue039 0.39 0.39 numValue04 0.4 0.4 numValue041 0.41 0.41 numValue042 0.42 0.42 numValue043 0.43 0.43 numValue044 0.44 0.44 numValue045 0.45 0.45 numValue046 0.46 0.46 numValue047 0.47 0.47 numValue048 0.48 0.48 numValue049 0.49 0.49 numValue05 0.5 0.5 numValue051 0.51 0.51 numValue052 0.52 0.52 numValue053 0.53 0.53 numValue054 0.54 0.54 numValue055 0.55 0.55 numValue056 0.56 0.56 numValue057 0.57 0.57 numValue058 0.58 0.58 numValue059 0.59 0.59 numValue06 0.6 0.6 numValue061 0.61 0.61 numValue062 0.62 0.62 numValue063 0.63 0.63 numValue064 0.64 0.64 numValue065 0.65 0.65 numValue066 0.66 0.66 numValue067 0.67 0.67 numValue068 0.68 0.68 numValue069 0.69 0.69 numValue07 0.7 0.7 numValue071 0.71 0.71 numValue072 0.72 0.72 numValue073 0.73 0.73 numValue074 0.74 0.74 numValue075 0.75 0.75 numValue076 0.76 0.76 numValue077 0.77 0.77 numValue078 0.78 0.78 numValue079 0.79 0.79 numValue08 0.8 0.8 numValue081 0.81 0.81 numValue082 0.82 0.82 numValue083 0.83 0.83 numValue084 0.84 0.84 numValue085 0.85 0.85 numValue086 0.86 0.86 numValue087 0.87 0.87 numValue088 0.88 0.88 numValue089 0.89 0.89 numValue09 0.9 0.9 numValue091 0.91 0.91 numValue092 0.92 0.92 numValue093 0.93 0.93 numValue094 0.94 0.94 numValue095 0.95 0.95 numValue096 0.96 0.96 numValue097 0.97 0.97 numValue098 0.98 0.98 numValue099 0.99 0.99 numValue1 1 1
誤差が発生しました。一部(というよりほぼすべて)の属性で加算した少数が扱われなくなっています。
その9
各属性に 0.0000000000000000001
を加算した場合。
$ npx ts-node src/script.ts 0.0000000000000000001 numValue001 0.01 0.01 numValue002 0.02 0.02 numValue003 0.03 0.03 numValue004 0.04 0.04 numValue005 0.05 0.05 numValue006 0.06 0.06 numValue007 0.07 0.07 numValue008 0.08 0.08 numValue009 0.09 0.09 numValue01 0.1 0.1 numValue011 0.11 0.11 numValue012 0.12 0.12 numValue013 0.13 0.13 numValue014 0.14 0.14 numValue015 0.15 0.15 numValue016 0.16 0.16 numValue017 0.17 0.17 numValue018 0.18 0.18 numValue019 0.19 0.19 numValue02 0.2 0.2 numValue021 0.21 0.21 numValue022 0.22 0.22 numValue023 0.23 0.23 numValue024 0.24 0.24 numValue025 0.25 0.25 numValue026 0.26 0.26 numValue027 0.27 0.27 numValue028 0.28 0.28 numValue029 0.29 0.29 numValue03 0.3 0.3 numValue031 0.31 0.31 numValue032 0.32 0.32 numValue033 0.33 0.33 numValue034 0.34 0.34 numValue035 0.35 0.35 numValue036 0.36 0.36 numValue037 0.37 0.37 numValue038 0.38 0.38 numValue039 0.39 0.39 numValue04 0.4 0.4 numValue041 0.41 0.41 numValue042 0.42 0.42 numValue043 0.43 0.43 numValue044 0.44 0.44 numValue045 0.45 0.45 numValue046 0.46 0.46 numValue047 0.47 0.47 numValue048 0.48 0.48 numValue049 0.49 0.49 numValue05 0.5 0.5 numValue051 0.51 0.51 numValue052 0.52 0.52 numValue053 0.53 0.53 numValue054 0.54 0.54 numValue055 0.55 0.55 numValue056 0.56 0.56 numValue057 0.57 0.57 numValue058 0.58 0.58 numValue059 0.59 0.59 numValue06 0.6 0.6 numValue061 0.61 0.61 numValue062 0.62 0.62 numValue063 0.63 0.63 numValue064 0.64 0.64 numValue065 0.65 0.65 numValue066 0.66 0.66 numValue067 0.67 0.67 numValue068 0.68 0.68 numValue069 0.69 0.69 numValue07 0.7 0.7 numValue071 0.71 0.71 numValue072 0.72 0.72 numValue073 0.73 0.73 numValue074 0.74 0.74 numValue075 0.75 0.75 numValue076 0.76 0.76 numValue077 0.77 0.77 numValue078 0.78 0.78 numValue079 0.79 0.79 numValue08 0.8 0.8 numValue081 0.81 0.81 numValue082 0.82 0.82 numValue083 0.83 0.83 numValue084 0.84 0.84 numValue085 0.85 0.85 numValue086 0.86 0.86 numValue087 0.87 0.87 numValue088 0.88 0.88 numValue089 0.89 0.89 numValue09 0.9 0.9 numValue091 0.91 0.91 numValue092 0.92 0.92 numValue093 0.93 0.93 numValue094 0.94 0.94 numValue095 0.95 0.95 numValue096 0.96 0.96 numValue097 0.97 0.97 numValue098 0.98 0.98 numValue099 0.99 0.99 numValue1 1 1
誤差が発生しました。すべての属性で加算した少数が扱われなくなっています。
おわりに
Amazon DynamoDB の UpdateItem の Add 構文による数値計算で、小数点以下の誤差が出ないのか確認してみました。
小数点16位くらいから誤差が発生するようになりました。少数を含む数値属性の加減に Add 構文を使わない方が良さそうです。回避策としては、以下のようなものが考えられます。
- Add 構文を使わない:一度アイテムを取得した上で、計算および楽観的ロック(※)を伴う更新を行う(こちらが参考になります)
- Add 構文を使う:少数の最大位が分かっている場合は、保管時に整数に変換する
どなかたの参考になれば幸いです。
以上